"""
@Time ： 2024/1/2 14:29
@Auth ： 莫天杨
@File ：parse.py
@IDE ：PyCharm
@Motto:大道无术
"""
from packet.kc_15 import *
from utils.common.crc16 import crc16_modbus_little_endian


def parse_authcode(raw_data):
    dump = raw_data[2:-4]
    authcode_calc = crc16_modbus_little_endian(dump)
    authcode = raw_data[-4:-2]
    if authcode == authcode_calc:
        return f'{authcode}({authcode})'
    else:
        return f'BCC错误{authcode} 正确为:{authcode_calc}'


class JT808Parser:
    def __init__(self):
        self.message_types = {
            '0001': parse_0001_general_response,  # 终端通用应答
            '0002': parse_device_heartbeat,  # 终端心跳
            '0003': parse_terminal_logoff,  # 终端注销
            '0004': parse_query_server_time,  # 查询服务器时间'
            '0100': parse_register_info,  # 终端注册
            '0102': parse_auth_info,  # 终端鉴权
            '0200': parse_location_info,  # 位置信息
            '8001': parse_8001_general_response,  # 平台通用应答
            '8103': parse_terminal_param_set    # 设置终端参数
            # Add more message types and their corresponding parsing methods here
        }

    def get_message_name(self, message_id):
        message_id_mapping = {
            '0001': '终端通用应答',
            '8001': '平台通用应答',
            '0002': '终端心跳',
            '8003': '补传分包请求',
            '0100': '终端注册',
            '8100': '终端注册应答',
            '0003': '终端注销',
            '0004': '查询服务器时间',
            '0102': '终端鉴权',
            '8103': '设置终端参数',
            '8104': '查询终端参数',
            '0104': '查询终端参数应答',
            '8105': '终端控制',  # 8105 终端控制
            '8106': '查询指定终端参数',
            '8107': '查询终端属性',
            '0107': '查询终端属性应答',
            '8108': '下发终端升级包',
            '0108': '终端升级结果通知',
            '0200': '位置信息汇报',
            '8201': '位置信息查询',
            '0201': '位置信息查询应答',
            '8202': '临时位置跟踪控制',
            '8203': '人工确认报警消息',
            '8300': '文本信息下发',
            '8301': '事件设置',
            '0301': '事件报告',
            '8302': '提问下发',
            '0302': '提问应答',
            '8303': '信息点播菜单设置',
            '0303': '信息点播/取消',
            '8304': '信息服务',
            '8400': '电话回拨',
            '8401': '设置电话本',
            '8500': '车辆控制',
            '0500': '车辆控制应答',
            '8600': '设置圆形区域',
            '8601': '删除圆形区域',
            '8602': '设置矩形区域',
            '8603': '删除矩形区域',
            '8604': '设置多边形区域',
            '8605': '删除多边形区域',
            '8606': '设置路线',
            '8607': '删除路线',
            '8700': '行驶记录仪数据采集命令',
            '0700': '行驶记录仪数据上传',
            '8701': '行驶记录仪参数下传命令',
            '0701': '电子运单上报',
            '0702': '驾驶员身份信息采集上报',
            '8702': '上报驾驶员身份信息请求',
            '0704': '定位数据批量上传',
            '0705': 'CAN 总线数据上传',
            '0800': '多媒体事件信息上传',
            '0801': '多媒体数据上传',
            '8800': '多媒体数据上传应答',
            '8801': '摄像头立即拍摄命令',
            '0805': '摄像头立即拍摄命令应答',
            '8802': '存储多媒体数据检索',
            '0802': '存储多媒体数据检索应答',
            '8803': '存储多媒体数据上传',
            '8804': '录音开始命令',
            '8805': '单条存储多媒体数据检索上传命令',
            '8900': '数据下行透传',
            '0900': '数据上行透传',
            '0901': '数据压缩上报',
            '8A00': '平台 RSA 公钥',
            '0A00': '终端 RSA 公钥',
            '8F00~8FFF': '平台下行消息保留',
            '0F00~0FFF': '终端上行消息保留',
            # 添加其他消息ID和对应的消息体名称
        }
        return message_id_mapping.get(message_id, '未知消息')

    def parse_header(self, raw_data):
        header = raw_data[2:36]  # 假设消息头固定长度为 17 字节
        data = {
            "包类型": JT808Parser.get_message_name(self, header[0:4]) + '(' + header[0:4] + ')',
            "消息体长度": str(int(header[4:8], 16) & 0x03FF) + '(' + header[4:8] + ')',
            "协议版本号": "2019" + '(' + header[8:10] + ')',
            "终端手机号": header[10:30],
            "消息流水号": header[30:34],
        }
        formatted_data = ""
        for key, value in data.items():
            formatted_data += f"{key}: {value}\n"
        return formatted_data

    def parse_body(self, raw_data):
        header = raw_data[2:36]  # 假设消息头固定长度为 12 字节
        protocol_id = header[0:4]
        body = raw_data[36:-4]
        # 根据消息ID调用对应的解析方法
        if protocol_id in self.message_types:
            parse_method = self.message_types[protocol_id]
            return f'原始数据: {body}\n' + parse_method(body)
        else:
            return "不支持解析的协议包: {}".format(protocol_id)

    def parse(self, raw_data):
        # 解析消息头
        header_result = self.parse_header(raw_data)
        # 将解析结果合并并返回
        return (f'原始数据：\n{" ".join([raw_data[i:i+2] for i in range(0, len(raw_data), 2)])}\n'
                f'{header_result}'
                f'------------------------------------------------------消息体------------------------------------------'
                f'------------\n{self.parse_body(raw_data)}'
                f'校 验 码：{parse_authcode(raw_data)}')





